import { useRef, useState } from "react";
import { PageContainer } from "@tarojs/components";
import Taro, { useDidShow, useRouter } from "@tarojs/taro";
import { useCreation } from "ahooks";
import bigjs from "big.js";

import ByRow from "@/components/ui/ByRow";
import Page from "@/components/common/Page";
import ByText from "@/components/ui/ByText";
import PopupShop from "./components/PopupShop";
import ByButton from "@/components/ui/ByButton";
import ListView from "@/components/app/ListView";
import MaterialSection from "./components/MaterialSection";

import ApiBudget from "@/api/budget";
import ApiMaterial from "@/api/material";
import useFetch from "@/hooks/useFetch";

import {
  MaterialAreaDetail,
  MaterialChooseTemp,
  MaterialDetailDTO,
} from "@/types/material";

/**
 * AddMaterialChooseRequest
 */
export interface FormMaterialChoose {
  chooseId: number;
  /**
   * 材料id
   */
  materialId: number;
  /**
   * 材料名称
   */
  materialName: string;
  /**
   * 价格
   */
  MaterialPrice: number;
  /**
   * 数量
   */
  num: number;
  /**
   * 备注
   */
  remark: string;
  /**
   * 使用价格名称
   */
  usePriceName: string;
  [property: string]: any;
}

export default ({ }) => {
  const { params } = useRouter<{
    intentCustomerId: `${number}`;
    /**
     * 材料类型：主材、灯具等
     */
    chooseType: `${number}`;
    /**
     * 2 已提交
     */
    status?: `${1 | 2}`;
    // 变更单据类型(中文的)
    chgBillType?: string;
  }>();

  // chooseType=1是主材，其他都是辅材，走变更单
  const chooseType = Number(params.chooseType);
  const intentCustomerId = Number(params.intentCustomerId);

  // 2时，表示不可编辑
  const isDisabled = params.status === "2";
  // 是否是变更单，如果是，走变更接口
  const isChangeOrder = chooseType !== 1;

  const hadRunAddBudChgMaster = useRef(false);
  // 拿到变更的ID
  const { data: budChgData, runAsync: runBudChgMaster } = useFetch(
    ApiBudget.addBudChgMaster,
    "POST",
    {
      manual: true,
    }
  );

  // 更新已选数据
  const { runAsync: updateChooseMaterial } = useFetch(
    () =>
      isChangeOrder
        ? ApiBudget.addBudChgDetail
        : ApiMaterial.materialChooseModify,
    "POST",
    {
      manual: true,
      onSuccess() {
        Taro.showToast({ icon: "none", title: "操作成功" });
      },
    }
  );

  // 材料模板
  const [materialList, setMaterialList] = useState<MaterialAreaDetail[]>([]);
  const setMaterialListRef = useRef(setMaterialList);

  // 根据意向客户ID获取材料模板
  const { loading, refresh } = useFetch<MaterialChooseTemp>(
    ApiMaterial.getMaterialInfoByintendId,
    {
      defaultParams: [{ intentCustomerId, chooseType }],
      onSuccess(res) {
        const newMap = new Map();
        // 把模板内的材料转成map形式
        res.Areas.forEach((area) => {
          area.DetailDTOList.forEach((item) => {
            item.MaterialCode && newMap.set(item.MaterialCode, item);
          });
        });

        setMaterialListRef.current(res.Areas);
      },
    }
  );

  const isMounted = useRef(true);

  useDidShow(() => {
    if (!isMounted.current) refresh();
    isMounted.current = false;
  });

  const [selected, setSelected] = useState<[] | [number, number]>([]);
  const selectedArea = materialList[selected[0]!];
  const selectedAreaItem = selectedArea?.DetailDTOList[selected[1]!];

  // 选择材料确认，更新进材料清单
  const setArea = async (index, subIndex, data) => {
    await handleUpdateChooseMaterial(data);

    materialList[index].DetailDTOList[subIndex] = { ...data, State: 0 };
    setMaterialList([...materialList]);
    setSelected([]);
  };

  const handleUpdateChooseMaterial = async (data: MaterialDetailDTO) => {
    // 当为变更单时，budChgData 中会有 budChgId属性
    let mergeBudData = budChgData;
    // 仅当是变更单时，才需要单独调这个接口，一次打开调一次就行了
    if (isChangeOrder && !hadRunAddBudChgMaster.current) {
      mergeBudData = await runBudChgMaster({ intentCustomerId, chooseType });
      hadRunAddBudChgMaster.current = true;
    }

    const obj = {
      num: data.Num,
      remark: data.Remark,
      chooseId: data.ChooseId,
      materialId: data.MaterialId,
      materialName: data.MaterialName,
      materialPrice: data.MaterialPrice,
      usePriceName: data.UsePriceName,
      color: data.Color,
      Standard: data.Standard,
      // -1未选材， 0已选
      // State: 0,

      ...(mergeBudData || {}),
    };

    await updateChooseMaterial(obj);
  };

  // 金额总计：
  const amountTotal = useCreation(() => {
    const res = materialList
      .map((e) => e.DetailDTOList)
      .flat()
      .reduce((total, item) => {
        // state == 0 表示已选（默认-1）
        if (item.State === 0 && item.Num > 0) {
          return total.plus(bigjs(item.MaterialPrice || 0).times(item.Num));
        }
        return total;
      }, bigjs(0));

    return res.toNumber();
  }, [materialList]);


  return (
    <>
      <Page
        footerSticky
        slotFooter={
          <ByRow align="center">
            <ByText>总计：¥{amountTotal}</ByText>

            {!isChangeOrder && !isDisabled && materialList.length > 0 && (
              <ByButton
                size="large"
                className="w-2/3 mr-0"
                to={`confirmation?intentCustomerId=${intentCustomerId}&chooseType=${chooseType}`}
              >
                确认选材
              </ByButton>
            )}
          </ByRow>
        }
      >
        <ListView loading={loading}>
          {materialList.map((area, index) => (
            <MaterialSection
              key={area.ChooseAreaId}
              source={area}
              disabled={isDisabled}
              setSelected={(subIndex) => setSelected([index, subIndex])}
              // 优化项：当外部source变化，也会导致setMaterialItem执行一次
              setMaterialItem={(subIndex, e) => setArea(index, subIndex, e)}
              onReset={() => refresh()}
            />
          ))}
        </ListView>
      </Page>

      <PageContainer
        round
        show={selected.length > 0}
        onLeave={() => setSelected([])}
      >
        {selected.length > 0 && (
          <PopupShop
            item={selectedAreaItem}
            chooseType={chooseType}
            intentCustomerId={intentCustomerId!}
            onCancel={() => setSelected([])}
            onConfirm={(item) => setArea(selected[0], selected[1], item)}
          />
        )}
      </PageContainer>
    </>
  );
};
